//
//  intrusive_iterator.hpp
//  utilities
//
//  Created by Sam Jaffe on 5/10/13.
//  Copyright (c) 2013 Sam Jaffe. All rights reserved.
//

#pragma once

template <typename N>
intrusive_iterator<N>::intrusive_iterator(N* node) :
node_(node) {
    
}

template <typename N>
auto intrusive_iterator<N>::operator*() -> reference {
    return *(node_->ptr_);
}

template <typename N>
auto intrusive_iterator<N>::operator*() const -> const_reference {
    return *(node_->ptr_);
}

template <typename N>
auto intrusive_iterator<N>::operator->() -> pointer {
    return node_->ptr_;
}

template <typename N>
auto intrusive_iterator<N>::operator->() const -> const_pointer {
    return node_->ptr_;
}

template <typename N>
intrusive_iterator<N> intrusive_iterator<N>::operator++(int) {
    intrusive_iterator<N> it{*this};
    node_ = node_->next_;
    return it;
}

template <typename N>
intrusive_iterator<N>& intrusive_iterator<N>::operator++() {
    node_ = node_->next_;
    return *this;
}

template <typename N>
intrusive_iterator<N> intrusive_iterator<N>::operator--(int) {
    intrusive_iterator<N> it{*this};
    node_ = node_->prev_;
    return it;
}

template <typename N>
intrusive_iterator<N>& intrusive_iterator<N>::operator--() {
    node_ = node_->prev_;
    return *this;
}

template <typename N>
N* intrusive_iterator<N>::get() {
    return node_;
}

template <typename N>
const N* intrusive_iterator<N>::get() const {
    return node_;
}

template <typename N>
bool intrusive_iterator<N>::operator==(const intrusive_iterator<N>& other) const {
    return node_ == other.node_;
}

template <typename N>
bool intrusive_iterator<N>::operator!=(const intrusive_iterator<N>& other) const {
    return node_ != other.node_;
}

#pragma mark const_intrusive_iterator
template <typename N>
const_intrusive_iterator<N>::const_intrusive_iterator(const N* node) :
node_(node) {
    
}

template <typename N>
auto const_intrusive_iterator<N>::operator*() const -> const_reference {
    return *(node_->ptr_);
}

template <typename N>
auto const_intrusive_iterator<N>::operator->() const -> const_pointer {
    return node_->ptr_;
}

template <typename N>
const_intrusive_iterator<N> const_intrusive_iterator<N>::operator++(int) {
    const_intrusive_iterator<N> it{*this};
    node_ = node_->next_;
    return it;
}

template <typename N>
const_intrusive_iterator<N>& const_intrusive_iterator<N>::operator++() {
    node_ = node_->next_;
    return *this;
}

template <typename N>
const_intrusive_iterator<N> const_intrusive_iterator<N>::operator--(int) {
    const_intrusive_iterator<N> it{*this};
    node_ = node_->prev_;
    return it;
}

template <typename N>
const_intrusive_iterator<N>& const_intrusive_iterator<N>::operator--() {
    node_ = node_->prev_;
    return *this;
}

template <typename N>
const N* const_intrusive_iterator<N>::get() const {
    return node_;
}

template <typename N>
bool const_intrusive_iterator<N>::operator==(const const_intrusive_iterator<N>& other) const {
    return node_ == other.node_;
}

template <typename N>
bool const_intrusive_iterator<N>::operator!=(const const_intrusive_iterator<N>& other) const {
    return node_ != other.node_;
}
